#include <string>

#include "BlockQueue.hpp"
#include "Task.hpp"
using namespace std;

#include <unistd.h>

#include <ctime>

// 定义可能的运算符
string opers = "+-*/%";

// 消费者线程函数
void *Consumer(void *args) {
  // 将传入的参数转换为 BlockQueue<Task> 指针
  BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
  while (true) {
    // 从队列中取出一个任务
    usleep(500000);

    Task task = bq->pop();
    // 执行任务
    task();
    // 打印任务执行结果
    printf(
        "The thread-%3lu handled a task , %2d %c %2d = %3d , exit code : %d\n",
        pthread_self() % 1000, task.getnum1(), task.getoper(), task.getnum2(),
        task.getresult(), task.getexitcode());
  }
  return nullptr;
}

// 生产者线程函数
void *Productor(void *args) {
  int len = opers.size();
  // 将传入的参数转换为 BlockQueue<Task> 指针
  BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
  while (true) {
    // 休眠0.5秒，控制生产速度
    usleep(500000);
    // 随机生成两个操作数和一个运算符
    int data1 = rand() % 10;
    int data2 = rand() % 10;
    char op = opers[rand() % len];
    // 创建新任务
    Task t(data1, data2, op);
    // 将任务推入队列
    bq->push(t);
    // 打印生成的任务信息
    printf("The thread-%3lu push a task ,%2d %c %2d = ? \n",
           pthread_self() % 1000, data1, op, data2);
  }
  return nullptr;
}

int main() {
  // 初始化随机数生成器
  srand(time(nullptr));

  // 创建一个 BlockQueue<Task> 对象作为共享队列
  BlockQueue<Task> *bq = new BlockQueue<Task>();

  // // 声明线程ID变量
  // pthread_t c_tid, p_tid;

  // 创建消费者线程
  pthread_t c_tids[3], p_tids[5];
  for (int i = 0; i < 3; ++i) {
    pthread_create(c_tids + i, nullptr, Consumer, bq);
  }
  // 创建生产者线程
  for (int i = 0; i < 3; ++i) {
    pthread_create(p_tids + i, nullptr, Productor, bq);
  }
  // 等待线程结束（实际上是无限等待）
  for (int i = 0; i < 3; ++i) pthread_join(c_tids[i], nullptr);
  for (int i = 0; i < 3; ++i) pthread_join(p_tids[i], nullptr);

  // 清理资源（实际上不会执行到这里）
  delete bq;
  return 0;
}

//--------------------------------------------------------------------------------

// // 定义可能的运算符
// string opers = "+-*/%";

// // 消费者线程函数
// void *Consumer(void *args) {
//   // 将传入的参数转换为 BlockQueue<Task> 指针
//   BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
//   while (true) {
//     // 从队列中取出一个任务
//     Task task = bq->pop();
//     // 执行任务
//     task();
//     // 打印任务执行结果
//     printf(
//         "The thread-%3lu handled a task , %2d %c %2d = %3d , exit code :
//         %d\n", pthread_self() % 1000, task.getnum1(), task.getoper(),
//         task.getnum2(), task.getresult(), task.getexitcode());
//     cout << "------------------------------------" << endl;
//   }
//   return nullptr;
// }

// // 生产者线程函数
// void *Productor(void *args) {
//   int len = opers.size();
//   // 将传入的参数转换为 BlockQueue<Task> 指针
//   BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
//   while (true) {
//     // 休眠0.5秒，控制生产速度
//     usleep(500000);
//     // 随机生成两个操作数和一个运算符
//     int data1 = rand() % 10;
//     int data2 = rand() % 10;
//     char op = opers[rand() % len];
//     // 创建新任务
//     Task t(data1, data2, op);
//     // 将任务推入队列
//     bq->push(t);
//     // 打印生成的任务信息
//     printf("The thread-%3lu push a task ,%2d %c %2d = ? \n",
//            pthread_self() % 1000, data1, op, data2);
//   }
//   return nullptr;
// }

// int main() {
//   // 初始化随机数生成器
//   srand(time(nullptr));

//   // 创建一个 BlockQueue<Task> 对象作为共享队列
//   BlockQueue<Task> *bq = new BlockQueue<Task>();

//   // 声明线程ID变量
//   pthread_t c_tid, p_tid;

//   // 创建消费者线程
//   pthread_create(&c_tid, nullptr, Consumer, bq);

//   // 创建生产者线程
//   pthread_create(&p_tid, nullptr, Productor, bq);

//   // 等待线程结束（实际上是无限等待）
//   pthread_join(c_tid, nullptr);
//   pthread_join(p_tid, nullptr);

//   // 清理资源（实际上不会执行到这里）
//   delete bq;
//   return 0;
// }
